package tests;

import static org.junit.Assert.*;

import java.io.File;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import conference.*;


public class TestConference {
	private Conference myConference;
	private String myTitle = "Test Conferecne";
	private List<Manuscript> myManuscriptList;
	private String myFileString = "The test file.";
	private Author myAuthor;
	private Manuscript myManuscript;
	private List<ProgramChair> myPcList;
	
	@Before
	public void setUpConference() {
		myManuscriptList = new ArrayList<Manuscript>();
		myPcList = new ArrayList<ProgramChair>();
		myAuthor = new Author();
		myManuscript = new Manuscript(myAuthor, 
				new File(myFileString), myTitle);
		myManuscriptList.add(myManuscript);
		myConference = new Conference(myTitle, new Date(), 
				new Date(), new Date(), 
				myManuscriptList, myPcList);
	}
	@Test
	public void testUpdateManuscriptAcceted() {
		Manuscript old = 
			myConference.getAllManuscripts()[0];
		myConference.updateManuscript(old, 
				Status.ACCEPTED);
		assertSame("Updated manuscript is not ACCEPTED", 
				Status.ACCEPTED,
				myConference.getAllManuscripts()[0].
				getStatus());
	}
	@Test
	public void testUpdateManuscriptDenied() {
		Manuscript old = 
			myConference.getAllManuscripts()[0];
		myConference.updateManuscript(old, 
				Status.DENIED);
		assertSame("Updated manuscript is not DENIED", 
				Status.DENIED,
				myConference.getAllManuscripts()[0].
				getStatus());
	}
	@Test
	public void testUpdateManuscriptUndecided() {
		Manuscript old = 
			myConference.getAllManuscripts()[0];
		myConference.updateManuscript(old, 
				Status.UNDECIDED);
		assertSame("Updated manuscript is not UNDECIDED", 
				Status.UNDECIDED,
				myConference.getAllManuscripts()[0].
				getStatus());
	}
	@Test
	public void testUpdateManuscriptSize() {
		int old_size = 
			myConference.getAllManuscripts().length;
		
		Manuscript old = 
			myConference.getAllManuscripts()[0];
		
			myConference.updateManuscript(old, 
					Status.ACCEPTED);
		
		int new_size = 
			myConference.getAllManuscripts().length;
		
		assertSame("Updated manuscript list size is not " +
				"equal to old size", old_size, new_size);
	}
	@Test
	public void testUpdateManuscriptNPE() {
		myManuscriptList.clear();
		try 
		{
			myConference.updateManuscript(null, 
					Status.ACCEPTED);
			fail("No NPE exception");
		} catch (NullPointerException e) {
			// all is well if this is caught.
		}
	}
	/**
	 * Tests the getManuscriptsByAuthor method
	 * @author Allison Graham
	 */
	@Test
	public void testGetManuscripstsByAuthor() {
		//test if pulling right manuscript.
		int numManuscripts = 
			myConference.getAllManuscripts().length;
		System.out.println("Num Manuscripts: " + 
				numManuscripts);
		System.out.println("Author for Manuscript: " + 
				myConference.getAllManuscripts()[0].
				getAuthor().getLastCommaFirst());
		assertTrue("There should only be one manuscript " +
				"by Author , ", 
				myConference.
				getManuscriptByAuthor(myAuthor).
				length == numManuscripts);
	}
	/**
	 * Tests the getManuscriptsByReviewer method
	 * @author Allison Graham
	 */
	@Test
	public void testGetManuscripstsByReviewer() {
		//test if pulling right manuscript.
		Reviewer testReviewer = 
			new Reviewer("Graham", 
					"Allison", 
					"grahaaj@gmail.com");
		myConference.submitReview(myManuscript, 
				new Review(testReviewer));
		int numManuscripts = myConference.
				getAllManuscripts().length;
		System.out.println("Num Manuscripts: " + 
				numManuscripts);
		Manuscript man = myConference.
				getAllManuscripts()[0];
		Review rev = man.getReviews().get(0);
		String name = rev.getReviewer().
				getLastCommaFirst();
		System.out.println("Reviewer for Manuscript: " + 
				name);
		assertTrue("There should only be one manuscript " +
				"by Reviewer Graham, Allison.", 
				myConference.
				getManuscriptByReviewer(testReviewer).
				length == numManuscripts);
	}
	
	
	/**
	 * Submits a given review for a given manuscript.
	 * <pre>
	 * -precondition : the_manuscript is not null.
	 * -postcondition : my_manuscript_list.size() 
	 * is equal to \old my_manuscript>list.size().
	 * -postcondition : the_manuscript.getReviews().size() 
	 * should equal new_manuscript.getReviews().size() + 1.
	 * -postcondition : the_review should be in 
	 * new_manuscript.getReviews().
	 * </pre>
	 * @param the_manuscript the manuscript to receive 
	 * the review.
	 * @param the_review the review to add to the 
	 * manuscript
	 * @author Allison Graham
	 * @return true if the review is successfully 
	 * submitted.
	 */
	@Test
	public void testSubmitReview() {
		Reviewer testReviewer = new Reviewer("Graham", "Allison", "grahaaj@gmail.com");
		myConference.submitReview(myManuscript, new Review(testReviewer));
		int oldNumReviews = myConference.getAllManuscripts()[0].getReviews().size();
		System.out.println("Num of Reviews: " + oldNumReviews);
		int numManuscripts = myConference.getAllManuscripts().length;
		System.out.println("Num Manuscripts: " + numManuscripts);
		Reviewer newReviewer = new Reviewer("Katie", "Park", "myemail@yahoo.com");
		Review newReview = new Review(newReviewer);
		int oldNumManuscript = myConference.getAllManuscripts().length;
		Manuscript myOldManuscript = myConference.getAllManuscripts()[0];
		myConference.submitReview(myOldManuscript, newReview);
		Manuscript myNewManuscript = myConference.getAllManuscripts()[0];
		
		assertTrue("my_manuscript_list.size() is equal to old my_manuscript>list.size()",
				oldNumManuscript == myConference.getAllManuscripts().length);
		assertTrue("the_manuscript.getReviews().size() should equal new_manuscript.getReviews().size() + 1",
				myOldManuscript.getNumberOfReviews() == myNewManuscript.getNumberOfReviews() - 1);
		assertSame("the_review should be in new_manuscript.getReviews()",
				newReview, myNewManuscript.getReviews().get(1));
	}
	
	/**
	 * Test submit Manuscript
	 */
	@Test
	public void testSubmitManuscript() {
		//TODO Check that size is plus one and one added if past deadline.
	}
	
	/**
	 * @author Dan Garrison
	 * @version Fall 2011
	 */
	@Test
	public void testGetUserRoles() {
		User testUser = new User("Scotty",
				"Hawthorne", "shawthorne@awesome.com");
		Author testAuthor = new Author(
			testUser.getFirstName(),
			testUser.getLastName(),
			testUser.getEmail()
		);
		ProgramChair testPC = new ProgramChair(
			testUser.getFirstName(),
			testUser.getLastName(),
			testUser.getEmail()				
		);
		Reviewer testReviewer = new Reviewer(
			testUser.getFirstName(),
			testUser.getLastName(),
			testUser.getEmail()					
		);
		Manuscript testMan = new Manuscript(
				testAuthor,
				new File("test file"),
				"Test File"
			);
		User[] roles;
		myConference.addProgramChair(testPC);
		myConference.submitManuscript(testMan);
		myConference.submitReview(testMan, 
				new Review(testReviewer));
		roles = myConference.getRolesByUser(testUser);
		User[] targetRoles = {
			testPC,
			testReviewer,
			testAuthor,
			
		};
		assertEquals("roles and targetRoles sizes are " +
				" not the same", targetRoles.length, 
				roles.length);		
	}
	
	/**
	 * ensures that there are not duplicate roles per user
	 * @author Dan Garrison
	 * @version Fall 2011
	 */
	@Test
	public void testGetUserRolesDuplicates() {
		Author testAuthor = new Author("Scotty",
				"Hawthorne", "shawthorne@awesome.com");
		Manuscript testMan1 = new Manuscript(
				testAuthor,
				new File("test file"),
				"Test File"
			);
		Manuscript testMan2 = new Manuscript(
				testAuthor,
				new File("test file"),
				"Test File"
			);
		User[] roles;
		myConference.submitManuscript(testMan1);
		myConference.submitManuscript(testMan2);
		roles = myConference.getRolesByUser(testAuthor);
		assertEquals("There are duplicate author roles",
				1, roles.length);		
	}
	/**
	 * ensures that any user can be an author
	 * @author Dan Garrison
	 * @version Fall 2011
	 */
	@Test
	public void testGetUserRolesDefaultAuthor() {
		ProgramChair testPc = new ProgramChair("Scotty",
				"Hawthorne", "shawthorne@awesome.com");
		User[] roles;
		roles = myConference.getRolesByUser(testPc);
		assertEquals("Un-roled not allowed to implicitly" +
				"take on author role",
				1, roles.length);		
	}
}
